package ru.spb.osll.myfit.server;

import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.Vector;

import ru.spb.osll.myfit.common.Content;
import ru.spb.osll.myfit.common.PageElement;
import ru.spb.osll.myfit.common.Table;
import ru.spb.osll.myfit.server.fixtureiterator.FileFactory;
import ru.spb.osll.myfit.server.handler.ContentCreator;
import ru.spb.osll.myfit.server.handler.ContentHandler;
import ru.spb.osll.myfit.server.handler.Handler;
import ru.spb.osll.myfit.server.handler.PageLoader;
import ru.spb.osll.myfit.server.parser.TableUtils;
import ru.spb.osll.myfit.server.templateloader.JarTableTemplateLoader;
import ru.spb.osll.myfit.server.templateloader.TableTemplateLoader;
import ru.spb.osll.myfit.util.StringUtils;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

@SuppressWarnings("serial")
public class CreateHelperServiceImpl extends RemoteServiceServlet implements
    ru.spb.osll.myfit.client.service.CreateHelperService {
  
  //private Logger log = Logger.getLogger(getClass());
  private Converter m_converter = new Converter();
  private TableTemplateLoader m_templateLoader;
  private TreeMap<String, String> m_templates;
  private Handler m_contentHandler;
  private Map<String, Class< ? >> m_fixtureClasses;
  private Configurator m_configurator;
  private ContentCreator m_contentCreator;
  
  public CreateHelperServiceImpl() {
    m_configurator = Configurator.getInstance();
    URLClassLoader m_classLoader = new MyFitClassLoaderFactory(new FileFactory()).createClassLoader(m_configurator.getJars(),
        m_configurator.getFixtures());
    m_templateLoader = new JarTableTemplateLoader(m_configurator.getFixtures(), m_classLoader);
    m_fixtureClasses = m_templateLoader.getFixtureClasses();
    m_templates = new TreeMap<String, String>(new FixtureNameComparator());
    for (Map.Entry<String, Class< ? >> entry : m_fixtureClasses.entrySet()) {
      Class< ? > clazz = entry.getValue();
      m_templates.put(StringUtils.splitCamelCase(clazz.getSimpleName()), entry.getKey());
    }

    HashMap<String, Class<?>> map = new HashMap<String, Class<?>>();
    for(Class<?> clazz : m_fixtureClasses.values()){
      map.put(StringUtils.splitCamelCase(clazz.getSimpleName()), clazz);
    }
    PageLoader pageLoader = new PageLoader(new TableUtils(map));
    m_contentCreator = new ContentCreator(m_configurator.getRoot());
    m_contentHandler = new ContentHandler(m_configurator.getRoot(), pageLoader);
  }

  @Override
  public TreeMap<String, String> loadTemplates() throws Exception {
    TreeMap<String, String> map = new TreeMap<String, String>();
    map.putAll(m_templates);
    return map;
  }

  @Override
  public Table getTemplate(String name) throws Exception {
    Class< ? > clazz = m_fixtureClasses.get(name);
    Vector<String> rawTable = m_templateLoader.getTemplate(clazz.getName());
    Table table = m_contentHandler.getTable(rawTable, TableUtils.getTableStyle(clazz));
    return table;
  }

  public String convertWikiToHtml(String wikiText) {
    return m_converter.convertWikiToHtml(wikiText);
  }

  public PageElement loadInclude(String pagePath, String includePath) {
    return m_contentHandler.loadInclude(includePath, pagePath);
  }

  @Override
  public PageElement createContent(int level, String pagePath){
    Content content = m_contentCreator.createContent(pagePath, level);
    return content;
  }
}
